Provide complete implementation of std::function, std::function_ref, and std::move_only_function equivalent to those in the C++26 <functional> header.
- Macro-free implementation
- The size of each specialization is two pointers
- Not require RTTI
- Support classes without
operator()
The implementation does not guarantee the best performance under all use cases but provides adequate code size & quality while maintaining full conformance.1
| Toolset | Standard Library | Test Environment |
|---|---|---|
| GCC >= 11.1.0 | libstdc++ | Ubuntu 20.04 |
| MSVC >= 14.30 | Microsoft STL | Visual Studio 2022 |
| Clang >= 17.0.6 | libc++ | Xcode 16.0 |
It's a header-only library. You may also install and consume its CMake targets:
find_package(nontype_functional CONFIG REQUIRED)
target_link_libraries("main" PRIVATE std23::nontype_functional)#include <std23/function_ref.h>
using std23::function_ref;
void parse_ini(function_ref<size_t(char *, size_t)> read_cb);
...
#include <stdio.h>
int main()
{
auto fp = ::fopen("my.ini", "r");
parse_ini([fp](auto ptr, auto n)
{ return ::fread(ptr, 1, n, fp); });
::fclose(fp);
}Ignore the fact that the code has no error handling or resource-safety; the callable wrappers, function_ref in the example, generalized the idea of callbacks. You can pass anything with a matching call pattern to another function, parse_ini in here, without turning the latter into a template.
Now, what if you have an existing class that can read data, but it's not a function object?
class data_source
{
...
public:
auto read(char *, size_t) -> size_t;
};Then you may designate a named member function, read in this example, to serve the role of an operator():
using std23::nontype;
int main()
{
data_source input;
parse_ini({nontype<&data_source::read>, input});
}The nontype tag generalized the idea of delegates from other languages, like C♯. What replaces operator() doesn't have to be a member function. You can also use a free function or even a lambda:
int main()
{
auto fp = ::fopen("my.ini", "r");
parse_ini({nontype<[](FILE *fh, auto ptr, auto n)
{ return ::fread(ptr, 1, n, fh); }>,
fp});
::fclose(fp);
}Feels like creating a member function for FILE on the fly, isn't it?
- 0.8 –
std::function_ref&std::function - 0.9 –
std::move_only_function - 1.0 –
nontype_tconstructors formove_only_function - 1.1 –
copyable_functionfrom P2548 - 1.2 – Support C++20 modules
cppreference page for std::function
cppreference page for std::move_only_function
cppreference page for std::function_ref
Footnotes
-
Except for
std::function'starget()member function, which is unimplemented because it requires RTTI. ↩